package com.ilxqx.framework.system.controller;

import com.google.common.collect.Lists;
import com.ilxqx.framework.security.config.SecurityConfigProperties;
import com.ilxqx.framework.system.controller.base.AbstractFrameworkController;
import com.ilxqx.framework.system.entity.SysPermission;
import com.ilxqx.framework.system.form.search.SysPermissionSearchForm;
import com.ilxqx.framework.system.form.update.SysPermissionUpdateForm;
import com.ilxqx.framework.system.service.SysPermissionService;
import com.ilxqx.framework.util.ResultUtils;
import com.ilxqx.framework.vo.ResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统权限控制器
 * @author venus
 */
@Api("系统权限控制器")
@RestController
@RequestMapping("/auth/sys-permission")
@Slf4j
public class SysPermissionController extends AbstractFrameworkController<SysPermission, Long, SysPermissionSearchForm, SysPermissionUpdateForm> {

	private final SysPermissionService sysPermissionService;
	private final JdbcTemplate jdbcTemplate;
	private final RequestMappingHandlerMapping handlerMapping;
	private final SecurityConfigProperties securityConfigProperties;

	@Autowired
	public SysPermissionController(SysPermissionService sysPermissionService, JdbcTemplate jdbcTemplate, @Qualifier("requestMappingHandlerMapping") RequestMappingHandlerMapping handlerMapping, SecurityConfigProperties securityConfigProperties) {
		super(sysPermissionService);
		this.sysPermissionService = sysPermissionService;
		this.jdbcTemplate = jdbcTemplate;
		this.handlerMapping = handlerMapping;
		this.securityConfigProperties = securityConfigProperties;
	}

	/**
	 * 是否自定义数据获取
	 *
	 * @return bool
	 */
	@Override
	public boolean isCustomGetListData() {
		return true;
	}

	/**
	 * 自定义list数据获取
	 *
	 * @return 数据
	 */
	@Override
	public Object customGetListData() {
		List<SysPermission> sysPermissionList = this.sysPermissionService.getListByParentPermissionId(0L);
		return this.flatPermissions(sysPermissionList, 0);
	}

	/**
	 * 将子元素进行扁平化
	 * @param sysPermissionList 权限列表
	 * @return 权限列表
	 */
	private List<SysPermission> flatPermissions(List<SysPermission> sysPermissionList, int level) {
		sysPermissionList.sort(Comparator.comparing(SysPermission::getCreateTime));
		return sysPermissionList
				.stream()
				.map(sysPermission -> {
					String name = StringUtils.repeat('+', level) + " " + sysPermission.getName();
					sysPermission.setName(name.trim());
					if (sysPermission.getChildren() != null && sysPermission.getChildren().size() > 0) {
						List<SysPermission> children = sysPermission.getChildren();
						children.sort(Comparator.comparing(SysPermission::getCreateTime));
						sysPermission.setChildren(null);
						List<SysPermission> flatList = Lists.newArrayList(sysPermission);
						flatList.addAll(this.flatPermissions(children, level + 1));
						return flatList;
					}
					return Lists.newArrayList(sysPermission);
				})
				.flatMap(Collection::stream)
				.collect(Collectors.toList());
	}

	/**
	 * 获取系统中的所有权限
	 * @return 系统权限
	 */
	@ApiOperation("获取系统中的所有权限")
	@GetMapping("/permissions")
	public ResultVO getRoles() {
		List<SysPermission> sysPermissionList = this.sysPermissionService.getListByParentPermissionId(0L);
		this.sort(sysPermissionList);
		return ResultUtils.success("成功", sysPermissionList);
	}

	/**
	 * 权限排序
	 * @param sysPermissions 待排序权限
	 */
	private void sort(List<SysPermission> sysPermissions) {
		sysPermissions.sort(Comparator.comparing(SysPermission::getCreateTime));
		sysPermissions.forEach(sysPermission -> {
			List<SysPermission> children = sysPermission.getChildren();
			if (children != null && !children.isEmpty()) {
				this.sort(children);
			}
		});
	}

	/**
	 * 在实体删除之后的处理
	 *
	 * @param entity 删除完的实体对象
	 * @return 返回数据
	 */
	@Override
	public Object afterDelete(SysPermission entity) {
		this.jdbcTemplate.update("delete from sys_role_permission where permission_id = ?", entity.getPermissionId());
		return null;
	}

	/**
	 * 获取请求映射
	 * @return 结果对象
	 */
	@ApiOperation("获取请求映射")
	@GetMapping("/mappings")
	public ResultVO getMappings() {
		Set<String> urls = new HashSet<>();
		Set<String> exclude = new HashSet<>();
		exclude.addAll(Arrays.asList(this.securityConfigProperties.getAllowedUrls()));
		exclude.addAll(Arrays.asList(this.securityConfigProperties.getAuthenticatedUrls()));
		handlerMapping
				.getHandlerMethods()
				.forEach((key, value) -> key
						.getPatternsCondition()
						.getPatterns()
						.forEach(url -> {
							if (!exclude.contains(url)) {
								urls.add(url);
							}
						}));
		return ResultUtils.success("成功", urls);
	}

}
